<template>
  <div class="query-form">
    <el-form ref="formRef" :model="queryForm" :rules="rules" inline>
      <el-form-item label="是否在职" prop="is_leave" style="width: 200px">
        <el-select v-model="queryForm.is_leave">
          <el-option label="离职" value="0" />
          <el-option label="在职" value="1" />
        </el-select>
      </el-form-item>

      <el-form-item label="月" prop="month">
        <el-date-picker
          style="width: 150px"
          v-model="queryForm.month"
          :clearable="false"
          type="month"
          value-format="YYYY-MM"
        />
      </el-form-item>

      <el-form-item label="根据类型查询" prop="type">
        <el-select v-model="queryForm.type" :disabled="isDimission" style="width: 150px">
          <el-option label="全部" value="all" />
          <el-option label="清洁工" value="cleaner" />
          <el-option label="办公室" value="office" />
          <el-option label="门店全职" value="fullTimeEmployee" />
          <el-option label="门店兼职" value="partTimeEmployee" />
          <el-option label="高级店长" value="superManager" />
        </el-select>
      </el-form-item>
      <!-- <el-form-item
        v-if="queryForm.type === 'attendanceGroup'"
        label="考勤组"
        prop="attendanceGroupId"
       >
        <attendance-group-selector
          v-model="queryForm.attendanceGroupId"
          placeholder="请选择考勤组"
        />
      </el-form-item> -->

      <el-form-item label="门店" prop="shopId">
        <shop-cascadar
          :disabled="!isFlack"
          v-model:shop-id="queryForm.shopId"
          type="shopId"
          :flacktype="queryForm.type"
          :is_leave="queryForm.is_leave"
        />
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="handleQueryClick">查询</el-button>
        <el-button type="primary" @click="handleExportClick">导出</el-button>
        <el-button type="primary" @click="handlePrintClick">打印</el-button>
        <el-button type="primary" @click="handlePayrollGeneration">生成工资表</el-button>
      </el-form-item>
    </el-form>
  </div>
  <el-table
    v-loading="isLoading"
    :cell-style="cellStyle"
    :data="attendances"
    border
    height="75vh"
    @cell-click="handleCellClick"
  >
    <el-table-column fixed label="ID" prop="userid" />
    <el-table-column fixed label="姓名" prop="username" />
    <el-table-column fixed label="办公地点">
      <template #default="{ row }">
        {{
          row.locattionOfWork !== undefined
            ? translateLocationOfWork(row.locattionOfWork)
            : undefined
        }}
      </template>
    </el-table-column>
    <el-table-column fixed label="人员类型">
      <template #default="{ row }">
        {{
          row.typeOfEmployment !== undefined
            ? translateTypeOfEmployment(row.typeOfEmployment)
            : undefined
        }}
      </template>
    </el-table-column>
    <el-table-column fixed label="所属门店" prop="shop_name" />
    <el-table-column
      v-for="(day, index) in days"
      :key="index"
      :label="day !== undefined ? formatDateStringToYearMonthDay(day) : undefined"
    >
      <template #default="{ row }">
        <div
          v-if="day !== undefined && findAttendanceRecordByDay(row, day) !== undefined"
        >
          <span
            v-for="(dayStatus, index) in findAttendanceRecordByDay(row, day)?.day_status"
          >
            <span v-if="index < 1">{{ dayStatus }}</span>
            <span v-if="index == 1">...</span>
          </span>
        </div>
      </template>
    </el-table-column>
  </el-table>
  <div class="pagination">
    <el-pagination
      v-model:current-page="queryForm.pageNumber"
      v-model:page-size="queryForm.pageSize"
      :page-count="totalPages"
      :page-sizes="[10, 20, 50, 100]"
      background
      layout="prev, pager, next, jumper, sizes"
      @change="handlePaginationChange"
    />
  </div>
  <attendance-record-drawer
    v-model="isViewDrawerShow"
    :attendance-record="attendanceRecordToView"
    :username="usernameToView"
    :userid="useridToView"
    @success="handleDrawerSuccess"
  />
</template>

<script lang="ts" setup>
import { computed, CSSProperties, ref, watch } from "vue";
import { AttendanceRecord, AttendanceResponse } from "@/api/types/attendance";
import AttendanceGroupSelector from "@/components/selector/AttendanceGroupSelector.vue";
import {
  getAttendancesByAttendanceGroupIdAndMonthAndPages,
  getAttendancesByMonthAndPages,
  getAttendancesByShopIdAndMonthAndPages,
  getAttendancesOfCleanersByMonthAndPages,
  getAttendancesOfFullTimeEmployeesByMonthAndPages,
  getAttendancesOfOfficeByMonthAndPages,
  getAttendancesOfPartTimeEmployeesByMonthAndPages,
  getAttendancesOfShopManagersByMonthAndPages,
  getPayrollGeneration,
} from "@/api/attendance";
import { ElForm, ElMessage, FormRules } from "element-plus";
import { isAxiosError } from "axios";
import AttendanceRecordDrawer from "@/components/drawer/AttendanceRecordDrawer.vue";
import { utils, writeFile } from "xlsx";
import print from "print-js";
import ShopCascadar from "@/components/cascader/ShopCascadar.vue";
import { formatDateStringToYearMonthDay, formatDateToYearAndMonth } from "@/utils/date";
import { translateLocationOfWork, translateTypeOfEmployment } from "@/api/types/employee";

const attendances = ref<AttendanceResponse[]>([]);
const days = computed(() => [
  ...new Set(
    attendances.value.flatMap((attendance) =>
      attendance.attendanceRecord.map((attendanceRecord) => attendanceRecord.day)
    )
  ),
]);
const totalPages = computed(() => attendances.value[0]?.total_pages);
const usernameToView = ref<string>();
const useridToView = ref<string>();
const attendanceRecordToView = ref<AttendanceRecord>();
const isViewDrawerShow = ref(false);
const isLoading = ref(false);

const queryForm = ref<{
  type:
    | "all"
    | "attendanceGroup"
    | "cleaner"
    | "fullTimeEmployee"
    | "office"
    | "partTimeEmployee"
    | "shop"
    | "superManager"
    | "";
  attendanceGroupId: number | undefined;
  shopId?: number;
  month: string;
  pageNumber: number;
  pageSize: number;
  is_leave: "0" | "1";
}>({
  type: "all",
  attendanceGroupId: undefined,
  month: formatDateToYearAndMonth(new Date()),
  pageNumber: 1,
  pageSize: 10,
  is_leave: "1",
});
const formRef = ref<InstanceType<typeof ElForm>>();

const rules = ref<FormRules>({
  month: [
    {
      required: true,
      message: "月不能为空",
      trigger: "change",
    },
  ],
  is_leave: [
    {
      required: true,
      message: "请选择查询类型",
      trigger: "change",
    },
  ],
});

computed(() => {});

const isFlack = computed(() => {
  let flacks = false;
  if (queryForm.value.type == "fullTimeEmployee") {
    flacks = true;
  } else if (queryForm.value.type == "partTimeEmployee") {
    flacks = true;
  } else {
    flacks = false;
  }

  return flacks;
});

const isDimission = computed(() => {
  let flacks = false;
  if (queryForm.value.is_leave == "0") {
    flacks = true;
    queryForm.value.type = "all";
    rules.value.type = undefined;
  } else {
    flacks = false;
    queryForm.value.type = "all";
    rules.value.type = [
      {
        required: true,
        message: "请选择查询类型",
        trigger: "change",
      },
    ];
  }
  return flacks;
});

watch(
  () => queryForm.value.type,
  (newValue, oldValue) => {
    switch (oldValue) {
      case "attendanceGroup": {
        rules.value.attendanceGroupId = undefined;
        break;
      }
      case "partTimeEmployee": {
        queryForm.value.shopId = undefined;
        rules.value.shopId = undefined;
        break;
      }
      case "fullTimeEmployee": {
        queryForm.value.shopId = undefined;
        rules.value.shopId = undefined;
        break;
      }
    }
    switch (newValue) {
      case "attendanceGroup": {
        rules.value.attendanceGroupId = [
          {
            required: true,
            message: "考勤组不能为空",
            trigger: "change",
          },
        ];
        break;
      }
      case "fullTimeEmployee": {
        rules.value.shopId = [
          {
            required: true,
            message: "门店不能为空",
            trigger: "change",
          },
        ];
        break;
      }
      case "partTimeEmployee": {
        rules.value.shopId = [
          {
            required: true,
            message: "门店不能为空",
            trigger: "change",
          },
        ];
        break;
      }
    }
  }
);

// 优先级排序
function sortAttendanceRecords(records: any): string[] {
  // 定义一个映射来关联出勤状态和它们的优先级
  const priorityMap: { [key: string]: number } = {
    缺卡: 1,
    迟到: 2,
    早退: 3,
    正常: 4,
  };
  // 使用Array.prototype.sort()方法进行排序
  return records.sort((a: string | number, b: string | number) => {
    // 根据priorityMap中的值比较两个元素
    return priorityMap[a] - priorityMap[b];
  });
}

function cellStyle({
  row,
  column,
}: {
  row: AttendanceResponse;
  column: { label: string };
}) {
  const style: CSSProperties = {};
  const dayStatus = findAttendanceRecordByDay(row, column.label)?.day_status;

  if (dayStatus !== undefined) {
    sortAttendanceRecords(findAttendanceRecordByDay(row, column.label)?.day_status);
    style.color = "white";
    style.cursor = "pointer";
    if (
      dayStatus.some((value) => value == "缺卡") ||
      dayStatus.some((value) => value == "无排班")
    ) {
      style.backgroundColor = "#F56C6C";
    } else if (dayStatus.some((value) => value === "迟到" || value === "早退")) {
      style.backgroundColor = "#E6A23C";
    } else {
      style.backgroundColor = "#67C23A";
    }
  }
  return style;
}

function attendancesForExportAndPrint() {
  const daysArray = days.value
    .filter((day) => day !== undefined)
    .map((day) => formatDateStringToYearMonthDay(day!));
  const processedData: AttendanceForExcel[] = attendances.value.map(
    (attendance: AttendanceResponse) => {
      const row = {
        ID: attendance.userid,
        姓名: attendance.username,
        办公地点:
          attendance.locattionOfWork !== undefined
            ? translateLocationOfWork(attendance.locattionOfWork)
            : undefined,
        人员类型:
          attendance.typeOfEmployment !== undefined
            ? translateTypeOfEmployment(attendance.typeOfEmployment)
            : undefined,
        所属门店: attendance.shop_name ?? "无",
      } as AttendanceForExcel;
      attendance.attendanceRecord.forEach((attendanceRecord, index) => {
        row[daysArray[index]] = attendanceRecord.day_status?.join("、");
      });
      return row;
    }
  );
  return { daysArray, processedData };
}

async function getData() {
  if (isLoading.value == false) {
    isLoading.value = true;
  }
  switch (queryForm.value.type) {
    case "all": {
      const { data } = await getAttendancesByMonthAndPages(
        queryForm.value.month,
        queryForm.value.pageNumber,
        queryForm.value.pageSize,
        queryForm.value.is_leave
      );
      if (data !== undefined) {
        attendances.value = data;
        isLoading.value = false;
      }
      break;
    }
    case "attendanceGroup": {
      if (queryForm.value.attendanceGroupId !== undefined) {
        const { data } = await getAttendancesByAttendanceGroupIdAndMonthAndPages(
          queryForm.value.attendanceGroupId,
          queryForm.value.month,
          queryForm.value.pageNumber,
          queryForm.value.pageSize,
          queryForm.value.is_leave
        );
        if (data !== undefined) {
          attendances.value = data;
          isLoading.value = false;
        }
      }
      break;
    }
    case "cleaner": {
      const { data } = await getAttendancesOfCleanersByMonthAndPages(
        queryForm.value.month,
        queryForm.value.pageNumber,
        queryForm.value.pageSize,
        queryForm.value.is_leave
      );
      if (data !== undefined) {
        attendances.value = data;
        isLoading.value = false;
      }
      break;
    }
    case "fullTimeEmployee": {
      const { data } = await getAttendancesOfFullTimeEmployeesByMonthAndPages(
        queryForm.value.month,
        queryForm.value.pageNumber,
        queryForm.value.pageSize,
        queryForm.value.shopId,
        queryForm.value.is_leave
      );
      if (data !== undefined) {
        attendances.value = data;
        isLoading.value = false;
      }
      break;
    }
    case "office": {
      const { data } = await getAttendancesOfOfficeByMonthAndPages(
        queryForm.value.month,
        queryForm.value.pageNumber,
        queryForm.value.pageSize,
        queryForm.value.is_leave
      );
      if (data !== undefined) {
        attendances.value = data;
        isLoading.value = false;
      }
      break;
    }
    case "partTimeEmployee": {
      const { data } = await getAttendancesOfPartTimeEmployeesByMonthAndPages(
        queryForm.value.month,
        queryForm.value.pageNumber,
        queryForm.value.pageSize,
        queryForm.value.shopId,
        queryForm.value.is_leave
      );
      if (data !== undefined) {
        attendances.value = data;
        isLoading.value = false;
      }
      break;
    }
    case "shop": {
      if (queryForm.value.shopId !== undefined) {
        const { data } = await getAttendancesByShopIdAndMonthAndPages(
          queryForm.value.shopId,
          queryForm.value.month,
          queryForm.value.pageNumber,
          queryForm.value.pageSize,
          queryForm.value.is_leave
        );
        if (data !== undefined) {
          attendances.value = data;
          isLoading.value = false;
        }
      }
      break;
    }
    case "superManager": {
      const { data } = await getAttendancesOfShopManagersByMonthAndPages(
        queryForm.value.month,
        queryForm.value.pageNumber,
        queryForm.value.pageSize,
        queryForm.value.is_leave
      );
      if (data !== undefined) {
        attendances.value = data;
        isLoading.value = false;
      }
      break;
    }
  }
}

// 根据日期查询某个人的考勤明细
function findAttendanceRecordByDay(attendanceResponse: AttendanceResponse, day: string) {
  return attendanceResponse.attendanceRecord.find(
    (attendanceResponse) => attendanceResponse.day === day
  );
}

function handleCellClick(row: AttendanceResponse, column: { label: string }) {
  // 通过 switch 语句判断只有在点击日期列时才打开抽屉展示考勤状态

  switch (column.label) {
    case "ID":
    case "姓名":
    case "办公地点":
    case "人员类型":
    case "所属门店":
      break;
    default: {
      isViewDrawerShow.value = true;
      usernameToView.value = row.username;
      useridToView.value = row.userid;
      attendanceRecordToView.value = findAttendanceRecordByDay(row, column.label);
    }
  }
}

// 修改考勤记录成功后
async function handleDrawerSuccess() {
  await getData();
}

interface AttendanceForExcel {
  ID?: string;
  姓名?: string;
  办公地点?: string;
  人员类型?: string;
  所属门店?: string;

  [day: string]: string | undefined;
}

function handleExportClick() {
  if (attendances.value.length > 0) {
    const { daysArray, processedData } = attendancesForExportAndPrint();
    const workBook = utils.book_new();
    const workSheet = utils.json_to_sheet(processedData, {
      header: ["ID", "姓名", "办公地点", "人员类型", "所属门店", ...daysArray],
    });
    utils.book_append_sheet(workBook, workSheet);
    writeFile(workBook, "output.xlsx");
  } else {
    ElMessage.error("没有数据可以导出");
  }
}

async function handlePrintClick() {
  if (attendances.value.length > 0) {
    const { daysArray, processedData } = attendancesForExportAndPrint();
    print({
      printable: processedData,
      type: "json",
      properties: ["ID", "姓名", "办公地点", "人员类型", "所属门店", ...daysArray],
      documentTitle: queryForm.value.month,
    });
  } else {
    ElMessage.error("没有数据可以打印");
  }
}

async function handleQueryClick() {
  formRef.value?.validate(async (isValid: boolean) => {
    if (isValid) {
      try {
        await getData();
      } catch (error) {
        if (isAxiosError(error) && error.response?.data.message != undefined) {
          ElMessage.error(error.response?.data.message);
        }
      }
    } else {
      switch (queryForm.value.type) {
        case "attendanceGroup": {
          ElMessage.error("请选择查询类型、考勤组和月份");
          break;
        }
        case "partTimeEmployee": {
          ElMessage.error("请选择查询类型、门店、月份");
          break;
        }
        case "fullTimeEmployee": {
          ElMessage.error("请选择查询类型、门店、月份");
          break;
        }
        default: {
          ElMessage.error("表单校验错误");
          break;
        }
      }
    }
  });
}

async function handlePayrollGeneration() {
  formRef.value?.validate(async (isValid: boolean) => {
    if (isValid) {
      const res =await getPayrollGeneration({cal_month:queryForm.value.month})
      if (res.code=='200') {
        ElMessage.success(res.msg)  
      }else{
        ElMessage.error(res.msg)
      }
    } else {
      ElMessage.error("表单校验错误");
    }
  });
}

async function handlePaginationChange() {
  await getData();
}
</script>

<style lang="scss" scoped>
.query-form {
  .el-select {
    --el-select-width: 240px;
  }
}

.pagination {
  margin-top: 20px;
}
</style>
